package live.zs.securitytokenredis.config;

import live.zs.securitytokenredis.constant.CacheConstants;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;

import java.time.Duration;

/**
 * @author madison
 * @date Redis 配置类
 */

//自定义CacheManager Bean 就不需要此注解，如果不自定义，则只需要此注解CacheManager就能使用了
//@EnableCaching

//proxyBeanMethods = true 或不写，是Full模式
//proxyBeanMethods = false 是lite模式
//lite模式下，直接返回新实例对象。
//Spring 5.2.0+的版本，建议你的配置类均采用Lite模式去做，即显示设置proxyBeanMethods = false。
//Spring Boot在2.2.0版本（依赖于Spring 5.2.0）起就把它的所有的自动配置类的此属性改为了false，
// 即@Configuration(proxyBeanMethods = false)，提高Spring启动速度
//Full 全模式，proxyBeanMethods默认是true：使用代理，也就是说该配置类会被代理，直接从IOC容器之中取得bean对象，不会创建新的对象。
// SpringBoot总会检查这个组件是否在容器中是否存在，保持组件的单实例
//Lite 轻量级模式，proxyBeanMethods设置为false：每次调用@Bean标注的方法获取到的对象是一个新的bean对象,
// 和之前从IOC容器中获取的不一样，SpringBoot会跳过检查这个组件是否在容器中是否存在，保持组件的多实例
@Configuration(proxyBeanMethods = false)
//@RequiredArgsConstructor
//@AutoConfigureBefore(RedisAutoConfiguration.class)
public class CacheConfig {

    private final RedisConnectionFactory factory;

    // 构造器注入 同 @RequiredArgsConstructor
    public CacheConfig(RedisConnectionFactory factory) {
        this.factory = factory;
    }

    @Bean
    CacheManager cacheManager() {
        return RedisCacheManager
                .builder(factory)
                .cacheDefaults(
                        RedisCacheConfiguration.defaultCacheConfig()
                                .entryTtl(Duration.ofHours(1))
                ).withCacheConfiguration(CacheConstants.JWT_TOKEN,
                        RedisCacheConfiguration.defaultCacheConfig()
                                .entryTtl(Duration.ofSeconds(5))
                                .disableCachingNullValues())
                .withCacheConfiguration(CacheConstants.USER_DETAILS,
                        RedisCacheConfiguration.defaultCacheConfig()
                                .entryTtl(Duration.ofSeconds(30))
                                .disableCachingNullValues())
                .transactionAware()
                .build();
    }
}
